package com.ccn.ui.a1ui;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ComposeShader;
import android.graphics.LightingColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.Nullable;

import com.ccn.ui.R;

import java.util.Map;

/**
 * 第一章 UI核心
 * 第一节 UI绘制流程
 * 1.1.1UI绘制流程及原理
 * View如何被添加到屏幕窗口上
 * 1.创建顶层布局容器DecorView
 * 2.在顶层布局中加载基础布局ViewGroup
 * 3.将ContentView添加到基础布局中的FrameLayout中
 * <p>
 * View的绘制流程
 * 1、绘制入口
 * ActivityThread.handleResumeActivity
 * ->WindowManagerImpl.addView
 * ->WindowManagerGlobal.addView
 * 2、绘制类及方法
 * ViewRootImpl.setView
 * ->ViewRootImpl.requestLayout
 * ->scheduleTraversals()
 * ->doTraversal()
 * ->performTraversals()
 * 3、绘制三大步骤
 * 测量：ViewRootImpl.performMeasure
 * 布局：ViewRootImpl.performLayout
 * 绘制：ViewRootImpl.performDraw
 * <p>
 * 1.1.2UI绘制流程（测量，布局，绘制）
 * View = 模式 + 尺寸 ->MeasureSpec 32位int值
 * 00000000000000000000000000000000
 * MODE_MASK :11000000000000000000000000000000
 * ~MODE_MASK:00111111111111111111111111111111
 * SpecMode(前2位) + SpecSize（后30位）
 * 父容器不对View做任何限制，系统内部使用
 * public static final int UNSPECIFIED = 0 << 30;  00000000000000000000000000000000
 * 父容器检测出View的大小，View的大小就是SpecSize LayoutParams match_parent
 * public static final int EXACTLY=1<<MODE_SHIFT;  01000000000000000000000000000000
 * 父容器指定一个可用大小，View的大小不能超过这个数值 LayoutParams wrap_content
 * public static final int AT_MOST=2<<MODE_SHIFT;  10000000000000000000000000000000
 * <p>
 * MODE+SIZE ->MeasureSpec
 * <p>
 * MeasureSpec = mode + size
 * <p>
 * View的测量-确定DecorView的MeasureSpec
 * DecorView的MeasureSpec由窗口大小和自身的LayoutParams决定：
 * MATCH_PARENT 精确模式，窗口大小
 * WRAP_CONTENT 最大模式，最大为窗口大小
 * 固定大小 精确模式，大小为LayoutParams的大小
 * <p>
 * View的测量-确定View的MeasureSpec
 * View的MeasureSpec由父容器的MeasureSpec和自身的LayoutParams决定：
 * <p>
 * childLayoutParams\parentSpecMode EXACTLY      AT_MOST         UNSPECIFIED
 * dp                               EXACTLY      EXACTLY           EXACTLY
 * childSize    childSize         childSize
 * match_parent                     EXACTLY      AT_MOST         UNSPECIFIED
 * parentSize   parentSize            0
 * wrap_content                     AT_MOST      AT_MOST         UNSPECIFIED
 * parentSize   parentSize            0
 * ViewGroup measure =>onMeasure(测量子控件的宽高)=>setMeasuredDimension=>setMEasuredDimensionRaw(保存自己的宽高)
 * View measure =>onMeasure=>setMeasuredDimension=>setMEasuredDimensionRaw(保存自己的宽高)
 * <p>
 * ViewGroup layout(来确定自己的位置，4个点的位置)=>onLayout(进行子View的布局)
 * View layout(来确定自己的位置，4个点的位置)
 * <p>
 * ViewGroup
 * 绘制背景 drawBackground（canvas）
 * 绘制自己 onDraw（canvas）
 * 绘制子View dispatchDraw（canvas）
 * 绘制前景、滑动条等装饰 onDrawForeground（canvas）
 * <p>
 * View
 * 绘制背景 drawBackground（canvas）
 * 绘制自己 onDraw（canvas）
 * 绘制前景、滑动条等装饰 onDrawForeground（canvas）
 * <p>
 * onMeasure => onLayout =>onDraw
 */
public class A1_1UIPaintFlowPath extends View {
    private Paint mPaint;
    private Shader mShader;
    private Bitmap mBitmap;

    public A1_1UIPaintFlowPath(Context context) {
        this(context, null);
    }

    public A1_1UIPaintFlowPath(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public A1_1UIPaintFlowPath(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.test);

        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL);
/*        //设置画笔颜色
        mPaint.setColor(Color.RED);
        //设置Paint对象颜色，范围为0~255
        mPaint.setARGB(255,255,255,0);
        //设置alpha不透明度，范围为0~255
        mPaint.setAlpha(200);
        //抗锯齿
        mPaint.setAntiAlias(true);
        //描边效果
        mPaint.setStyle(Paint.Style.STROKE);
        //描边宽度
        mPaint.setStrokeWidth(4);
        //圆角效果
        mPaint.setStrokeCap(Paint.Cap.ROUND);
        //拐角效果
        mPaint.setStrokeJoin(Paint.Join.MITER);
        //设置环形渲染器
        mPaint.setShader(new SweepGradient(200,200,Color.BLUE,Color.RED));
        //设置图层混合模式
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
        //设置颜色过滤器
        mPaint.setColorFilter(new LightingColorFilter(0x00ffff,0x000000));
        //设置双线性过滤
        mPaint.setFilterBitmap(true);
        //设置画笔这招滤镜，传入度数和样式
        mPaint.setMaskFilter(new BlurMaskFilter(10, BlurMaskFilter.Blur.NORMAL));
        //设置文本缩放倍数
        mPaint.setTextScaleX(2);
        //设置字体大小
        mPaint.setTextSize(30);
        //对齐方式
        mPaint.setTextAlign(Paint.Align.LEFT);
        //设置下划线
        mPaint.setUnderlineText(true);

        String str = "Android高级工程师";
        Rect rect = new Rect();
        //测量文本大小，将文本大小信息存放到rect中
        mPaint.getTextBounds(str,0,str.length(),rect);
        //获取文本宽度
        mPaint.measureText(str);
        //获取字体度量对象
        mPaint.getFontMetrics();*/

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        //线性着色器
//        mShader = new LinearGradient(0, 0, 500, 500,
//                new int[]{Color.BLUE, Color.RED, Color.GREEN}, new float[]{0.3f, 0.7f, 1},
//                Shader.TileMode.CLAMP);
//        mPaint.setShader(mShader);
//        canvas.drawRect(0, 0, 500, 500, mPaint);

        //环形渲染器
//        mShader = new RadialGradient(250, 250, 250,
//                new int[]{Color.BLUE, Color.RED, Color.GREEN}, null,
//                Shader.TileMode.CLAMP);
//        mPaint.setShader(mShader);
//        canvas.drawCircle(250, 250, 250, mPaint);

        //扫描渲染
//        mShader = new SweepGradient(250, 250, Color.RED, Color.GREEN);
//        mPaint.setShader(mShader);
//        canvas.drawCircle(250, 250, 250, mPaint);

        //位图渲染
//        mShader = new BitmapShader(mBitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
//        mPaint.setShader(mShader);
////        canvas.drawRect(0,0,mBitmap.getWidth(),mBitmap.getHeight(), mPaint);
//        canvas.drawRect(0, 0, 500, 500, mPaint);

        BitmapShader bitmapShader = new BitmapShader(mBitmap, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
        LinearGradient linearGradient = new LinearGradient(0, 0, 500, 500,
                new int[]{Color.BLUE, Color.RED, Color.GREEN}, new float[]{0.3f, 0.7f, 1},
                Shader.TileMode.CLAMP);
        mShader = new ComposeShader(bitmapShader, linearGradient, PorterDuff.Mode.MULTIPLY);
        mPaint.setShader(mShader);
        canvas.drawCircle(250, 250, 250, mPaint);
    }
}
